#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include "logger.h"

#define BACKLOG		13

int socket_server_init(char *listen_ip, int listen_port)
{
	int			rv = 0;
	int			on = 1;
	int 			sockfd = -1;
	struct sockaddr_in	servaddr;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd < 0)
	{
		log_error("Socket() a new socket failure:%s\n", strerror(errno));
		return -1;
	}
	log_info("Socket() successfully!\n");

	//解决端口不能立马复用的问题
	setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	
	memset(&servaddr, 0, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(listen_port);

	//如果没传IP，服务器端将监听所有IP地址
	if(!listen_ip)
	{
		servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	}
	else
	{
		//将IP转换成4个字节存放在结构体套接字中
		if(inet_pton(AF_INET, listen_ip, &servaddr.sin_addr) < 0)
		{
			log_debug("inet_pton() set listen IP address failure:%s\n", strerror(errno));
			rv = -2;
			goto CleanUp;
		}
	}

	rv = bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
	if(rv < 0)
	{
		log_error("Bind on port[%d] failure:%s\n", listen_port, strerror(errno));
		rv = -3;
		goto CleanUp; 
	}
	log_info("Bind on port[%d] successfully!\n", listen_port);

	rv = listen(sockfd, BACKLOG);
	if(rv < 0)
	{
		log_error("Listen on port[%d] failure:%s\n", listen_port, strerror(errno));
		rv = -4;
		goto CleanUp;
	}

//如果函数执行正确，返回sockfd; 函数执行出错则返回rv的值
CleanUp:
	if(rv < 0)
	{
		close(sockfd);
	}
	else
	{
		rv = sockfd;
	}
	
	return rv;
}


